<?php
/**
 * CreateTime: 2022/6/6 10:03
 */

namespace App\Service\Approval;

use App\Consts\Approval\ApprovalCodeConsts;
use App\Consts\Approval\ApprovalSubmitTypeConsts;
use App\Consts\ClientConsts\ClientAuditConsts;
use App\Consts\ContractConsts\ContractSubTypeConsts;
use App\Consts\ResponseConsts\ResponseStatusConsts;
use App\Func\AppFunc;
use App\Func\ResponseFunc;
use App\Func\TokenFuc;
use App\Models\Approval\OldDingTalkApprovalModel;
use App\Models\File\FileModel;
use App\ServiceChecker\Client\ClientCreditLegitimacy;
use App\ServiceChecker\Client\ClientLegitimacy;
use App\Tools\DingTalk\DingTalkApprovalProcess;
use App\Tools\DingTalk\DingTalkDeptUserFacade;
use App\Tools\Log\Log;
use Exception;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\DB;
use JetBrains\PhpStorm\ArrayShape;

class PublicDingTalkApprovalService
{

    private function checkerApprovalDataBySource($args){
        if(@$args['clientChecker']){
           $checkerData = $args['clientChecker'];
           $clientLeg =  new ClientCreditLegitimacy();
           $clientLeg->verifyClientCreditIdClientIsExists($checkerData['clientId']);
           $clientLeg->verifyClientCreditSendProcessIsOK($checkerData['clientId']);
        }
    }

    /**
     * 发起审批人实例
     * @param $sourceType
     * @param $sourceId
     * @param $formComponent
     * @return mixed
     */
    public function sendApproval($sourceType,$sourceId,$formComponent,$dd_dept_id,$ex=[]){
        // 校验发起人
        $staffInfo = TokenFuc::getCurrentStaffInfo();
        $originatorUserId = @$staffInfo['dingTalkId'];
        if(!$originatorUserId){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前经办人没有绑定钉钉',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }

        $processDingTalkCode = "";
        switch ($sourceType){
            // 申请信用客户
            // 校验客户是否存在
            case ApprovalSubmitTypeConsts::SUBMIT_CREDIT_CLIENT:
			{
                $this->checkerApprovalDataBySource([
                    'clientChecker' => [
                        'clientId' => $sourceId
                    ]
                ]);
                $processDingTalkCode = AppFunc::getDingApprovalCode()::CLIENT_APPROVAL_CODE;
                break;
			}
            case ApprovalSubmitTypeConsts::SUBMIT_JOIN_BLACKLIST:
                $processDingTalkCode = AppFunc::getDingApprovalCode()::JOIN_BLACK_LIST_DING_APPROVAL_CODE;
                break;
            case ApprovalSubmitTypeConsts::SUBMIT_REMOVE_BLACKLIST:
                $processDingTalkCode = AppFunc::getDingApprovalCode()::REMOVE_BLACK_LIST_DING_APPROVAL_CODE;
                break;
            case ApprovalSubmitTypeConsts::SUBMIT_CONTRACT:
                $processDingTalkCode = AppFunc::getDingApprovalCode()::CONTRACT_APPROVAL_CODE;
                break;
            case ApprovalSubmitTypeConsts::SUBMIT_CONTRACT_LAW:
                $processDingTalkCode = AppFunc::getDingApprovalCode()::CONTRACT_APPROVAL_FW_CODE;
                break;
            case ApprovalSubmitTypeConsts::SUBMIT_SEAL_CONTRACT:
                $processDingTalkCode = AppFunc::getDingApprovalCode()::CONTRACT_SEAL_APPROVAL_CODE;
                break;
//            case ApprovalSubmitTypeConsts::SUBMIT_CREDIT_CLIENT:
//                $processDingTalkCode = ApprovalCodeConsts::CLIENT_APPROVAL_CODE;
//                break;

			# by breezeer
			# 
			# 
			case ApprovalSubmitTypeConsts::SUBMIT_CREDIT_PROJECT_CREDIT_DEPARTMENT_LEADER_REVIEW	:	{	$processDingTalkCode =  AppFunc::getDingApprovalCode()::CREDIT_PROJECT_DING_DING_APPROVAL_CODE					;	break;	} # 信用项目审批第三节点部门领导审查 
			case ApprovalSubmitTypeConsts::SUBMIT_CREDIT_PROJECT_CREDIT_AMOUNT_ADJUST_REVIEW		:	{	$processDingTalkCode =  AppFunc::getDingApprovalCode()::CREDIT_PROJECT_ADJUST_QUOTA_DING_DING_APPROVAL_CODE		;	break;	} # 信用项目审批已批准赊销项目额度的调增调减审查 

            default:
                $processDingTalkCode = "PROC-DA942348-5B1A-438C-96A7-9F064D89D7D6";
                break;
        }

		try {
            $err = false;
            DB::beginTransaction();
            $processId = DingTalkApprovalProcess::sendOldApprovalProcess([
                'code' => $processDingTalkCode,
                'originatorUserId' => $originatorUserId,
                'deptId' => $dd_dept_id,
                'formComponent' => $formComponent
            ],$err);

            // 绑定钉钉审批表
            $oldDingTalkModel = new OldDingTalkApprovalModel();
            // 绑定钉钉处理表
            $res = $oldDingTalkModel->addTalkApproval([
                'originator_staff_id' =>$staffInfo['staff_id'],
                'ding_talk_approval_process_id' =>$processId,
                'ding_talk_approval_type_id' => 2,
                'submit_approval_source_id' => $sourceId,
                'submit_approval_type' => $sourceType,
                'file_ids' => $ex['file_ids'] ?? "",
                'remark' => $ex['remark'] ?? "",
                "form_component" => json_encode($ex['sqlComponent'],JSON_UNESCAPED_UNICODE)
            ]);
            DB::commit();

			#
			#
			# app()->gcHelper->gfDebugPrintToLocalFileByBreezeer(['DingTalkApprovalProcess::sendOldApprovalProcess.$oldDingTalkModel' => $oldDingTalkModel]);


            return $res;
        }catch (Exception $exception){

			#
			#
			# app()->gcHelper->gfDebugPrintToLocalFileByBreezeer(['DingTalkApprovalProcess::sendOldApprovalProcess.$exception' => $exception]);


            Log::e("进入了回归");
            DB::rollBack();
            if($err){
                throw new HttpResponseException(ResponseFunc::returnJson(
                    'error',
                    null,
                    $err,
                    ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                ));
            }
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                $exception->getMessage(),
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
    }


    /**
     * 控件类型选择参考 https://open.dingtalk.com/document/orgapp-server/initiate-approval -> 支持的表单控件
     *
     *
     */

    /**
     *            支持的控件： 输入框
     *            多行输入框
     *            单选框（注意，单选框需要是预设在表单的值）
     *            日期（根据日期类型来传值，分别为“yyyy-mm-dd hh:mm” 和“yyyy-mm-dd”。）
     * @param string $componentName "合同编号"
     * @param string $input "HT-XXXX-XXX-XX"
     * @return string[]
     */
    #[ArrayShape(['name' => "", 'value' =>"string"])]
    public function setTextTextAreaText(string $componentName, string $input): array
    {
        return [
            'name' => $componentName,
            'value' => $input
        ];
    }
    public function setTextTextAreaTextByArray(string $componentName, array $input): array
    {
        return [
            'name'	=> $componentName,
            'value' => app()->gcHelper->gfJsonEncode($input)
        ];
    }

    /**
     *  支持的控件 金额/数字/计算公式
     * @param string $componentName "金额"
     * @param int $input  10
     * @return array
     */
    #[ArrayShape(['name' => "", 'value' => "int"])]
    public function setMoneyNumberFuc(string $componentName, int $input): array
    {
        return [
            'name' => $componentName,
            'value' => $input
        ];
    }

    /**
     *  日期区间
     *  ex：
     * @param array $componentName	=> "[\"开始时间\",\"结束时间\"]"
     * @param array $input			=> "[\"2019-02-19\",\"2019-02-25\"]"
	 *
	 * modify by BREEZEER @ 2020.08.03
	 *
	 *
	 *
     */
    public function setStartDateEndDate(array $componentName, array $input)
	{
        return	[
					'name'	=>"[\"".str_replace(['"','\''],'',$componentName[0]	)."\",\"".str_replace(['"','\''],'',$componentName[1]	)."\"]"
					,
					'value' =>"[\"".str_replace(['"','\''],'',$input[0]			)."\",\"".str_replace(['"','\''],'',$input[1]			)."\"]"
				];
    }

    /**
     * 联系人
     * ex:
     * @param string $componentName "联系人"
     * @param array $input ["userId","userId2"]
     */
    #[ArrayShape(['name' => "string", 'value' => "false|string"])]
    public function setLinkMan(string $componentName, array $input): array
    {
        return [
            'name' => $componentName,
            'value' => json_encode($input)
        ];
    }

    /**
     * @param string $componentName
     * @param array $input [["table1_name"=>11,"xx"=>"xx",...],["table2_name"=>22]]
     */
    public function setTable(string $componentName,array $input){
        return [
            'name' => $componentName,
            'value' => $input
        ];
    }

    /**
     * @param string $componentName
     * @param int $fileId
     */
    #[ArrayShape(['name' => "string", 'value' => "mixed|null"])]
//    public function setFile(string $componentName, int $fileId): array
//    {
//        $fileModel = new FileModel();
//        $getFileInfo = $fileModel->getFileById($fileId);
//        $approvalFile = @$getFileInfo['dingTalkSpaceInfo'];
//        if(!$approvalFile){
//            throw new HttpResponseException(ResponseFunc::returnJson(
//                'error',
//                null,
//                '当前文件未上传至钉盘',
//                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
//            ));
//        }
//        return [
//            'name' => $componentName,
//            'value' => $approvalFile
//        ];
//    }

    public function setFiles(string $componentName, string $fileIds){
        $fileModel = new FileModel();
        $getFileList = $fileModel->getFilesByIdSelect(explode(",",$fileIds),["dingTalkSpaceInfo"]);

        if($getFileList){
            $getFileList = $getFileList->toArray();
            $getFileList = array_column($getFileList,"dingTalkSpaceInfo");
            $data = [];
            foreach($getFileList as $value){
                $data[] = json_decode($value,true);
            }
            return [
                'name' => $componentName,
                'value' =>  json_encode($data)
            ];
        }else{
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '226 文件错误',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
    }

    public function setTableValue(string $key, string $name)
    {
        return [
            'name' => $key,
            'value' =>  $name
        ];
    }


}
